﻿#include "CrossObjectHolder.h"
#include "XyNet/Common/Exception.h"

namespace XyNet
{
	XYNET_IMPLEMENT_BASE_SINGLETON(CrossObjectHolder<string>);

	XYNET_API string* StringHold(const string& str)
	{
		try
		{
			return CrossObjectHolder<string>::getInstance()->add(make_shared<string>(str));
		}
		catch (const exception& e)
		{
			HandleException(e);
			return nullptr;
		}
	}

	XYNET_API string* StringCreate(byte* bytes, int length)
	{
		try
		{
			return CrossObjectHolder<string>::getInstance()->add(
				make_shared<string>((const char*)bytes, length));
		}
		catch (const exception& e)
		{
			HandleException(e);
			return nullptr;
		}
	}

	XYNET_API void StringDestroy(string* str)
	{
		try
		{
			CrossObjectHolder<string>::getInstance()->remove(str);
		}
		catch (const exception& e)
		{
			HandleException(e);
		}
	}

	XYNET_API int StringGetLength(string* str)
	{
		try
		{
			return numeric_cast<int>(str->size());
		}
		catch (const exception& e)
		{
			HandleException(e);
			return 0;
		}
	}

	XYNET_API void StringGetData(string* str, byte* outBytes)
	{
		try
		{
			memcpy(outBytes, str->data(), str->size());
		}
		catch (const exception& e)
		{
			HandleException(e);
		}
	}

	//////////////////////////////////////////////////////////////////////////

	//XYNET_IMPLEMENT_BASE_SINGLETON(CrossObjectHolder<Bytes>);

	XYNET_API Bytes* BytesHold(const Bytes& bytes)
	{
		try
		{
			return CrossObjectHolder<Bytes>::getInstance()->add(make_shared<Bytes>(bytes));
		}
		catch (const exception& e)
		{
			HandleException(e);
			return nullptr;
		}
	}

	XYNET_API Bytes* BytesCreate(byte* bytes, int length)
	{
		try
		{
			return CrossObjectHolder<Bytes>::getInstance()->add(
				make_shared<Bytes>((const char*)bytes, length));
		}
		catch (const exception& e)
		{
			HandleException(e);
			return nullptr;
		}
	}

	XYNET_API void BytesDestroy(Bytes* bytes)
	{
		try
		{
			CrossObjectHolder<Bytes>::getInstance()->remove(bytes);
		}
		catch (const exception& e)
		{
			HandleException(e);
		}
	}

	XYNET_API int BytesGetLength(Bytes* bytes)
	{
		try
		{
			return numeric_cast<int>(bytes->size());
		}
		catch (const exception& e)
		{
			HandleException(e);
			return 0;
		}
	}

	XYNET_API void BytesGetData(Bytes* bytes, byte* outBytes)
	{
		try
		{
			memcpy(outBytes, bytes->data(), bytes->size());
		}
		catch (const exception& e)
		{
			HandleException(e);
		}
	}

	//////////////////////////////////////////////////////////////////////////

	XYNET_IMPLEMENT_BASE_SINGLETON(CrossObjectHolder<vector<Bytes>>);

	XYNET_API vector<Bytes>* BytesVectorHold(const vector<Bytes>& bytess)
	{
		try
		{
			return CrossObjectHolder<vector<Bytes>>::getInstance()->add(
				make_shared<vector<Bytes>>(bytess));
		}
		catch (const exception& e)
		{
			HandleException(e);
			return nullptr;
		}
	}

	XYNET_API void BytesVectorDestroy(vector<Bytes>* bytess)
	{
		try
		{
			CrossObjectHolder<vector<Bytes>>::getInstance()->remove(bytess);
		}
		catch (const exception& e)
		{
			HandleException(e);
		}
	}

	XYNET_API int BytesVectorGetLength(vector<Bytes>* bytess)
	{
		try
		{
			return numeric_cast<int>(bytess->size());
		}
		catch (const exception& e)
		{
			HandleException(e);
			return 0;
		}
	}

	XYNET_API int BytesVectorGetBytesLength(vector<Bytes>* bytess, int index)
	{
		try
		{
			assert(index >= 0 && numeric_cast<size_t>(index) < bytess->size());
			return numeric_cast<int>(bytess->at(index).size());
		}
		catch (const exception& e)
		{
			HandleException(e);
			return 0;
		}
	}

	XYNET_API void BytesVectorGetBytesData(vector<Bytes>* bytess, int index, byte* outBytes)
	{
		try
		{
			assert(index >= 0 && numeric_cast<size_t>(index) < bytess->size());
			auto bytes = &bytess->at(index);
			memcpy(outBytes, bytes->data(), bytes->size());
		}
		catch (const exception& e)
		{
			HandleException(e);
		}
	}

	//////////////////////////////////////////////////////////////////////////

	XYNET_IMPLEMENT_BASE_SINGLETON(CrossObjectHolder<vector<void*>>);

	XYNET_API vector<void*>* PointerVectorCreate()
	{
		try
		{
			return CrossObjectHolder<vector<void*>>::getInstance()->add(
				make_shared<vector<void*>>());
		}
		catch (const exception& e)
		{
			HandleException(e);
			return nullptr;
		}
	}

	XYNET_API void PointerVectorDestroy(vector<void*>* v)
	{
		try
		{
			CrossObjectHolder<vector<void*>>::getInstance()->remove(v);
		}
		catch (const exception& e)
		{
			HandleException(e);
		}
	}

	XYNET_API void PointerVectorAdd(vector<void*>* v, void* pointer)
	{
		try
		{
			v->emplace_back(pointer);
		}
		catch (const exception& e)
		{
			HandleException(e);
		}
	}
}